package com.spring.lo.framework.factory.support;

import com.mysql.cj.util.StringUtils;
import com.spring.lo.framework.factory.config.BeanDefinition;
import com.spring.lo.framework.factory.config.PropertyValue;
import com.spring.lo.framework.util.ReflectionUtils;

import java.util.List;

/**
 * 抽象有自动装配能力的BeanFactory
 * 该类负责具体创建Bean的事情
 * @author zhangbh
 * 2023-05-28 22:35
 **/
public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFactory {

    @Override
    protected Object createBean(BeanDefinition bd) {
        // 创建Bean三部曲
        // a.创建Bean对象；
        Object bean = createInstance(bd);
        // b.注入Bean属性；
        populateBean(bean, bd);
        // c.执行 Bean init方法
        initializeBean(bean, bd);
        return bean;
    }

    private void initializeBean(Object bean, BeanDefinition bd) {
        String initMethod = bd.getInitMethod();
        if (StringUtils.isNullOrEmpty(initMethod)) {
            return;
        }
        Class<?> classType = bd.getClassType();
        ReflectionUtils.invokeMethod(classType, bean, initMethod);
    }

    private Object createInstance(BeanDefinition bd) {
        return ReflectionUtils.createInstance(bd.getClassType());
    }


    private void populateBean(Object bean, BeanDefinition bd) {
        List<PropertyValue> pvs = bd.getPropertyValues();
        Class<?> classType = bd.getClassType();
        for (PropertyValue pv : pvs) {
            String name = pv.getName();
            Object value = pv.getValue();
            if (value == null) {
                return;
            }
            BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this);
            // 解析实际类型
            Object valueToUse = valueResolver.parseValue(value);

            ReflectionUtils.setFieldValue(bean, classType, name, valueToUse);
        }
    }

}
